package handle

import (
	"duanju-mq/cache"
	"duanju-mq/db"
	"duanju-mq/pkg/formatStruct"
	"duanju-mq/pkg/log"
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

type BonusHistory struct {
	Id           int64  `json:"id" field:"id"`
	ActivityName string `json:"activity_name" field:"activity_name"`
	UserDeviceId string `json:"user_device_id" field:"user_device_id"`
	Expired      int64  `json:"expired" field:"expired"`           //过期时间
	Bonus        int64  `json:"bonus" field:"bonus"`               //赠送
	RemainBonus  int64  `json:"remain_bonus" field:"remain_bonus"` //剩余
	CreateAt     int64  `field:"create_at" json:"create_at"`
	UpdatedAt    int64  `field:"updated_at" json:"updated_at"`
	Deleted      int64  `field:"deleted" json:"deleted"` //  标识记录是否被删除（0：没有被删除，1：被删除）
}

type MqData struct {
	DeviceId string `json:"device_id"`
	UnlockId int64  `json:"unlock_id"`
	Bonus    int64  `json:"bonus"`
}

func HandleDecreaseBonus(rawData string) {

	info := MqData{}
	if err := json.Unmarshal([]byte(rawData), &info); err != nil {
		log.Err(fmt.Sprintf("HandleDecreaseBonus json.Unmarshal value:%v err:%+v", rawData, err))
		return
	}

	var (
		deviceId = info.DeviceId
		bonus    = info.Bonus
		unlockId = info.UnlockId
		now      = time.Now().Unix()

		querySQL = fmt.Sprintf(
			`UPDATE 
    					bonus_history 
					SET 
					   	remain_bonus = remain_bonus - ?,
					    updated_at = ? 
					WHERE id = ? AND deleted  = 0`)

		queryBonusCond = []string{
			"remain_bonus > 0",
			"user_device_id = ?",
			"expired > ?",
		}
		pageIndex = 1
		pageSize  = 10

		bonusConsume int64
		//记录扣减明细
		consumeDetail []*BonusHistory
	)

	for bonus > 0 {
		//获取一批有效bonus
		cond := fmt.Sprintf(" where %v order by expired asc limit ? offset ?", strings.Join(queryBonusCond, " and "))
		histories, err := getBonusHistoryFromDb(cond, deviceId, now, pageSize, (pageIndex-1)*pageSize)
		if err != nil {
			log.Err(err)
			return
		}
		//如果查不到数据，结束
		if len(histories) < 1 {
			break
		}
		//一条一条扣减
		for _, v := range histories {
			if bonus < 1 {
				break
			}
			if v.RemainBonus < 1 {
				continue
			}
			if v.RemainBonus < bonus {
				bonusConsume = v.RemainBonus
				bonus = bonus - v.RemainBonus
			} else {
				bonusConsume = bonus
				bonus = 0
			}
			_, err = db.MqDB().Exec(querySQL, bonusConsume, time.Now().Unix(), v.Id)
			if err != nil {
				log.Err(fmt.Sprintf("decreaseBonus %v bonusConsume:%v deviceId:%v %+v", querySQL, bonusConsume, deviceId, err))
				return
			}
			//保存扣减明细，这时候在unlock_order.bonus_details表中，RemainBonus的值表示：子集消耗了这条bonus_history的多少金币
			v.RemainBonus = bonusConsume
			consumeDetail = append(consumeDetail, v)
		}
		pageIndex++
	}
	if len(consumeDetail) > 0 {
		//更新即将过期bonus的缓存
		_ = cache.DeleteBonusUpcomingExpiredInfoCache(deviceId)
		detail, _ := json.Marshal(consumeDetail)

		//更新 unlock_order.bonus_details
		updateSql := "update `unlock_order` set `bonus_details`=? where `id`=?"
		_, err := db.MqDB().Exec(updateSql, detail, unlockId)
		if err != nil {
			log.Err(err)
		}
	}

}

func getBonusHistoryFromDb(sqlCond string, values ...interface{}) ([]*BonusHistory, error) {

	querySql := "select " + formatStruct.ParseStructFields(&BonusHistory{}).ColsToString() +
		fmt.Sprintf(" from bonus_history %v", sqlCond)

	rows, err := db.MqDB().Query(querySql, values...)
	if err != nil {
		log.Err(fmt.Sprintf("getBonusHistoryFromDb %v %+v %+v", querySql, values, err))
		return nil, err
	}
	defer rows.Close()

	var list []*BonusHistory
	for rows.Next() {
		item := &BonusHistory{}
		if err = rows.Scan(formatStruct.ParseStructFields(item).GetPtrs()...); err != nil {
			log.Err(fmt.Sprintf("getBonusHistoryFromDb %v %+v %+v", querySql, values, err))
			return nil, err
		}
		list = append(list, item)
	}

	return list, err
}
